"""
分析任务API接口
"""
from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks, Query
from sqlalchemy.orm import Session
from pydantic import BaseModel, Field
from typing import Dict, Any, List, Optional
from datetime import datetime
import uuid

from core.database import get_db
from core.logging_config import get_logger, log_api_request
from core.auth import get_current_active_user, require_permission
from core.exceptions import  ValidationError
from models.user import User
from models.analysis_task import TaskStatus, TaskType, ExecutionType, AnalysisTask, TaskService
from services.task_manager import task_manager, TaskPriority

# 路由器
analysis_tasks_router = APIRouter(tags=["分析任务"])

# 日志记录器
logger = get_logger("analysis_tasks_api")


class TaskCreateRequest(BaseModel):
    """创建任务请求"""
    name: str = Field(..., min_length=1, max_length=200, description="任务名称")
    task_type: str = Field(..., description="任务类型（支持多选，逗号分隔）")
    execution_type: str = Field(default=ExecutionType.SINGLE_ANALYSIS.value, description="执行类型")
    data_source_id: Optional[int] = Field(None, description="数据源ID")
    analysis_start_date: Optional[datetime] = Field(None, description="分析开始日期")
    analysis_end_date: Optional[datetime] = Field(None, description="分析结束日期")
    config: Dict[str, Any] = Field(default_factory=dict, description="任务配置")
    services: List[Dict[str, Any]] = Field(default_factory=list, description="服务配置列表")
    max_retries: int = Field(3, ge=0, le=10, description="最大重试次数")
    priority: TaskPriority = Field(TaskPriority.MEDIUM, description="任务优先级")


class TaskUpdateRequest(BaseModel):
    """更新任务请求"""
    name: Optional[str] = Field(None, min_length=1, max_length=200, description="任务名称")
    task_type: Optional[str] = Field(None, description="任务类型（支持多选，逗号分隔）")
    execution_type: Optional[str] = Field(None, description="执行类型")
    data_source_id: Optional[int] = Field(None, description="数据源ID")
    analysis_start_date: Optional[datetime] = Field(None, description="分析开始日期")
    analysis_end_date: Optional[datetime] = Field(None, description="分析结束日期")
    config: Optional[Dict[str, Any]] = Field(None, description="任务配置")
    services: Optional[List[Dict[str, Any]]] = Field(None, description="服务配置列表")
    max_retries: Optional[int] = Field(None, ge=0, le=10, description="最大重试次数")


class TaskResponse(BaseModel):
    """任务响应"""
    id: int
    name: str
    task_type: str
    execution_type: str
    status: str
    config: Dict[str, Any]
    services: List[Dict[str, Any]]
    data_source_id: Optional[int]
    analysis_start_date: Optional[datetime]
    analysis_end_date: Optional[datetime]
    creator_id: int
    progress: float
    total_count: int
    success_count: int
    failed_count: int
    start_time: Optional[datetime]
    end_time: Optional[datetime]
    duration: Optional[float]
    retry_count: int
    max_retries: int
    error_message: Optional[str]
    created_at: datetime
    updated_at: datetime
    
    class Config:
        from_attributes = True


class TaskListResponse(BaseModel):
    """任务列表响应"""
    total: int
    page: int
    page_size: int
    items: List[TaskResponse]


class TaskStatusResponse(BaseModel):
    """任务状态响应"""
    id: int
    name: str
    status: str
    progress: float
    total_count: int
    success_count: int
    failed_count: int
    start_time: Optional[datetime]
    end_time: Optional[datetime]
    duration: Optional[float]
    error_message: Optional[str]


class TaskDetailResponse(BaseModel):
    """任务详情响应"""
    task: TaskResponse
    services: List[Dict[str, Any]]


class TaskTemplateCreateRequest(BaseModel):
    """创建任务模板请求"""
    name: str = Field(..., min_length=1, max_length=200, description="模板名称")
    description: Optional[str] = Field(None, description="模板描述")
    task_type: str = Field(..., description="任务类型")
    category: Optional[str] = Field(None, description="模板分类")
    config: Dict[str, Any] = Field(..., description="任务配置")
    services: List[Dict[str, Any]] = Field(..., description="服务配置")
    field_mapping: Optional[Dict[str, Any]] = Field(None, description="字段映射")


@analysis_tasks_router.get("", response_model=TaskListResponse)
@log_api_request("list_analysis_tasks")
@require_permission("analysis_task:view")
async def list_analysis_tasks(
    task_status: Optional[str] = Query(None, description="任务状态过滤"),
    task_type: Optional[str] = Query(None, description="任务类型过滤"),
    execution_type: Optional[str] = Query(None, description="执行类型过滤"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取分析任务列表"""
    logger.info("获取分析任务列表请求")
    
    try:
        filters = {}
        if task_status:
            filters["status"] = task_status
        if task_type:
            filters["task_type"] = task_type
        if execution_type:
            filters["execution_type"] = execution_type
        
        result = task_manager.list_tasks(db, filters, page, page_size)
        
        return TaskListResponse(
            total=result["total"],
            page=result["page"],
            page_size=result["page_size"],
            items=result["items"]
        )
        
    except Exception as e:
        logger.error(f"获取分析任务列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.post("", response_model=TaskResponse)
@log_api_request("create_analysis_task")
@require_permission("analysis_task:create")
async def create_analysis_task(
    request: TaskCreateRequest,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """创建分析任务"""
    logger.info(f"创建分析任务请求: {request.name}")
    
    try:
        # 验证任务类型（支持多选，逗号分隔）
        valid_task_types = [t.value for t in TaskType]
        task_types = [t.strip() for t in request.task_type.split(',') if t.strip()]
        invalid_types = [t for t in task_types if t not in valid_task_types]
        
        if invalid_types:
            raise HTTPException(status_code=400, detail=f"不支持的任务类型: {', '.join(invalid_types)}。支持的类型: {', '.join(valid_task_types)}")
        
        if not task_types:
            raise HTTPException(status_code=400, detail="请至少选择一个任务类型")
        
        # 验证执行类型
        valid_execution_types = [t.value for t in ExecutionType]
        if request.execution_type not in valid_execution_types:
            raise HTTPException(status_code=400, detail=f"不支持的执行类型: {request.execution_type}。支持的类型: {', '.join(valid_execution_types)}")
        
        # 转换请求数据
        task_data = {
            "name": request.name,
            "task_type": request.task_type,
            "execution_type": request.execution_type,
            "data_source_id": request.data_source_id,
            "analysis_start_date": request.analysis_start_date,
            "analysis_end_date": request.analysis_end_date,
            "config": request.config,
            "services": request.services,
            "max_retries": request.max_retries
        }
        
        # 创建任务
        task = await task_manager.create_task(task_data, current_user.id, db)
        
        return TaskResponse.from_orm(task)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"创建分析任务失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.get("/{task_id}", response_model=TaskDetailResponse)
@log_api_request("get_analysis_task")
@require_permission("analysis_task:view")
async def get_analysis_task(
    task_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取分析任务详情"""
    logger.info(f"获取分析任务详情请求: {task_id}")
    
    try:
        detail = task_manager.get_task_detail(task_id, db)
        
        if not detail:
            raise HTTPException(status_code=404, detail="任务不存在")
        
        return TaskDetailResponse(**detail)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取分析任务详情失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.put("/{task_id}", response_model=TaskResponse)
@log_api_request("update_analysis_task")
@require_permission("analysis_task:edit")
async def update_analysis_task(
    task_id: int,
    request: TaskUpdateRequest,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """更新分析任务"""
    logger.info(f"更新分析任务请求: {task_id}")
    
    try:
        # 获取任务
        task = db.query(AnalysisTask).filter(AnalysisTask.id == task_id).first()
        if not task:
            raise HTTPException(status_code=404, detail="任务不存在")
        
        # 只能更新待执行的任务
        if task.status != TaskStatus.PENDING:
            raise HTTPException(status_code=400, detail="只能更新待执行的任务")
        
        # 更新字段
        if request.name is not None:
            task.name = request.name
        if request.task_type is not None:
            task.task_type = request.task_type
        if request.execution_type is not None:
            task.execution_type = request.execution_type
        if request.data_source_id is not None:
            task.data_source_id = request.data_source_id
        if request.analysis_start_date is not None:
            task.analysis_start_date = request.analysis_start_date
        if request.analysis_end_date is not None:
            task.analysis_end_date = request.analysis_end_date
        if request.config is not None:
            task.config = request.config
        if request.services is not None:
            task.services = request.services
        if request.max_retries is not None:
            task.max_retries = request.max_retries
        
        db.commit()
        db.refresh(task)
        
        return TaskResponse.from_orm(task)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新分析任务失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.delete("/{task_id}")
@log_api_request("delete_analysis_task")
@require_permission("analysis_task:delete")
async def delete_analysis_task(
    task_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """删除分析任务"""
    logger.info(f"删除分析任务请求: {task_id}")
    
    try:
        # 获取任务
        task = db.query(AnalysisTask).filter(AnalysisTask.id == task_id).first()
        if not task:
            raise HTTPException(status_code=404, detail="任务不存在")
        
        # 只能删除非运行中的任务
        if task.status == TaskStatus.RUNNING:
            raise HTTPException(status_code=400, detail="无法删除运行中的任务")
        
        # 删除相关服务记录
        db.query(TaskService).filter(TaskService.task_id == task_id).delete()
        
        # 删除任务
        db.delete(task)
        db.commit()
        
        return {"message": "任务删除成功"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除分析任务失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.post("/{task_id}/start")
@log_api_request("start_analysis_task")
@require_permission("analysis_task:execute")
async def start_analysis_task(
    task_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """启动分析任务"""
    logger.info(f"启动分析任务请求: {task_id}")
    
    try:
        success = await task_manager.execute_task(task_id, db)
        
        if success:
            return {"message": "任务启动成功"}
        else:
            raise HTTPException(status_code=500, detail="任务启动失败")
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"启动分析任务失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.post("/{task_id}/stop")
@log_api_request("stop_analysis_task")
@require_permission("analysis_task:execute")
async def stop_analysis_task(
    task_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """停止分析任务"""
    logger.info(f"停止分析任务请求: {task_id}")
    
    try:
        success = await task_manager.stop_task(task_id, db)
        
        if success:
            return {"message": "任务停止成功"}
        else:
            raise HTTPException(status_code=500, detail="任务停止失败")
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"停止分析任务失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.post("/{task_id}/retry")
@log_api_request("retry_analysis_task")
@require_permission("analysis_task:execute")
async def retry_analysis_task(
    task_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """重试分析任务"""
    logger.info(f"重试分析任务请求: {task_id}")
    
    try:
        success = await task_manager.retry_task(task_id, db)
        
        if success:
            return {"message": "任务重试成功"}
        else:
            raise HTTPException(status_code=500, detail="任务重试失败")
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"重试分析任务失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.get("/{task_id}/progress", response_model=TaskStatusResponse)
@log_api_request("get_task_progress")
@require_permission("analysis_task:view")
async def get_task_progress(
    task_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取任务进度"""
    logger.info(f"获取任务进度请求: {task_id}")
    
    try:
        status = task_manager.get_task_status(task_id, db)
        
        if not status:
            raise HTTPException(status_code=404, detail="任务不存在")
        
        return TaskStatusResponse(**status)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取任务进度失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.get("/templates/")
@log_api_request("list_task_templates")
@require_permission("analysis_task:view")
async def list_task_templates(
    category: Optional[str] = Query(None, description="模板分类"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取任务模板列表"""
    logger.info("获取任务模板列表请求")
    
    try:
        from models.analysis_task import TaskTemplate
        
        query = db.query(TaskTemplate)
        
        if category:
            query = query.filter(TaskTemplate.category == category)
        
        templates = query.filter(TaskTemplate.is_active == True).all()
        
        return {
            "templates": [template.to_dict() for template in templates],
            "total": len(templates)
        }
        
    except Exception as e:
        logger.error(f"获取任务模板列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.post("/templates/")
@log_api_request("create_task_template")
@require_permission("analysis_task:create")
async def create_task_template(
    request: TaskTemplateCreateRequest,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """创建任务模板"""
    logger.info(f"创建任务模板请求: {request.name}")
    
    try:
        from models.analysis_task import TaskTemplate
        
        # 验证任务类型
        valid_task_types = [t.value for t in TaskType]
        if request.task_type not in valid_task_types:
            raise HTTPException(status_code=400, detail=f"不支持的任务类型: {request.task_type}。支持的类型: {', '.join(valid_task_types)}")
        
        # 创建模板
        template = TaskTemplate(
            name=request.name,
            description=request.description,
            task_type=request.task_type,
            category=request.category,
            config=request.config,
            services=request.services,
            field_mapping=request.field_mapping,
            creator_id=current_user.id
        )
        
        db.add(template)
        db.commit()
        db.refresh(template)
        
        return {"message": "模板创建成功", "template_id": template.id}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"创建任务模板失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.get("/datasources/")
@log_api_request("get_task_datasources")
@require_permission("analysis_task:view")
async def get_task_datasources(
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取可用于任务的数据源列表"""
    logger.info("获取任务数据源列表请求")
    
    try:
        from models.data_source import DataSource
        
        datasources = db.query(DataSource).filter(
            DataSource.is_active == True
        ).all()
        
        return {
            "datasources": [
                {
                    "id": ds.id,
                    "name": ds.name,
                    "description": ds.description,
                    "type": ds.source_type,
                    "status": ds.status,
                    "record_count": ds.record_count
                }
                for ds in datasources
            ],
            "total": len(datasources)
        }
        
    except Exception as e:
        logger.error(f"获取任务数据源列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@analysis_tasks_router.get("/stats/summary")
@log_api_request("get_task_stats_summary")
@require_permission("analysis_task:view")
async def get_task_stats_summary(
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取任务统计摘要"""
    logger.info("获取任务统计摘要请求")
    
    try:
        from sqlalchemy import func
        
        # 基础统计
        total_tasks = db.query(AnalysisTask).count()
        pending_tasks = db.query(AnalysisTask).filter(AnalysisTask.status == TaskStatus.PENDING).count()
        running_tasks = db.query(AnalysisTask).filter(AnalysisTask.status == TaskStatus.RUNNING).count()
        completed_tasks = db.query(AnalysisTask).filter(AnalysisTask.status == TaskStatus.COMPLETED).count()
        failed_tasks = db.query(AnalysisTask).filter(AnalysisTask.status == TaskStatus.FAILED).count()
        
        # 今日统计
        today = datetime.now().date()
        today_tasks = db.query(AnalysisTask).filter(
            func.date(AnalysisTask.created_at) == today
        ).count()
        
        # 成功率
        success_rate = 0
        if completed_tasks + failed_tasks > 0:
            success_rate = completed_tasks / (completed_tasks + failed_tasks) * 100
        
        return {
            "total_tasks": total_tasks,
            "pending_tasks": pending_tasks,
            "running_tasks": running_tasks,
            "completed_tasks": completed_tasks,
            "failed_tasks": failed_tasks,
            "today_tasks": today_tasks,
            "success_rate": round(success_rate, 2)
        }
        
    except Exception as e:
        logger.error(f"获取任务统计摘要失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))